package pushserver

import (
	"net"
	"pushserver/protocol"
	"pushserver/serialize"
	"pushserver/ssl"
)

type TcpProxy struct {
	Proto   protocol.Protocol
	Seri    serialize.Serialize
	IsOnSSL bool
}

func (this *TcpProxy) Write(conn net.Conn, data interface{}) (int, error) {
	var err error
	var b []byte
	if b, err = this.Seri.Encode(data); err == nil {
		if this.IsOnSSL {
			if b, err = ssl.Encrypt(b); err == nil {
				b = this.Proto.Pakcet(b)
			}
		} else {
			b = this.Proto.Pakcet(b)
		}
		return conn.Write(b)
	}
	return 0, err
}

func (this *TcpProxy) Read(conn net.Conn) (chan []byte, error) {
	var err error
	var b []byte = make([]byte, 128)
	var i int
	if i, err = conn.Read(b); err == nil {
		b = b[:i]
		rdChan := make(chan []byte)
		if this.IsOnSSL {
			format := func(data []byte) []byte {
				if r, err := ssl.Decrypt(data); err != nil {
					return nil
				} else {
					return r
				}
			}
			this.Proto.Unpacket(b, rdChan, format)
		} else {
			this.Proto.Unpacket(b, rdChan, nil)
		}
		return rdChan, nil
	}
	return nil, err
}

func (this *TcpProxy) Deserialize(data []byte, v interface{}) error {
	return this.Seri.Decode(data, v)
}

func (this *TcpProxy) SSL(conn net.Conn) error {
	if this.IsOnSSL {
		return ssl.Handshake(conn)
	}
	return nil
}
